package ldh.im.rpc.util;

import ldh.im.rpc.connection.RpcDataChannel;
import ldh.im.rpc.connection.handle.RpcContext;
import ldh.im.rpc.connection.handle.RpcSession;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class RpcUtil {

    public static Class getRpcParam(Method method) {
        Class<?>[] classes = method.getParameterTypes();
        if (classes == null) return Void.class;
        for (Class clazz : classes) {
            if (!(RpcContext.class.isAssignableFrom(clazz) || RpcSession.class.isAssignableFrom(clazz) || RpcDataChannel.class.isAssignableFrom(clazz)) ) {
                return clazz;
            }
        }
        if (classes.length > 0) return classes[0];
        return Void.class;
    }

    public static Class<?>[] getMethodGenericityClass(Method method, Class<?> argClass) {
        Type[] paraTypees = method.getGenericParameterTypes();
        for (Type paraType : paraTypees) {

            if (paraType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) paraType;
                if (((Class)parameterizedType.getRawType()) != argClass) continue;
                Type[] argTypes = parameterizedType.getActualTypeArguments();
                Class<?> returnClasses[] = new Class[argTypes.length];
                int i = 0;
                for (Type argType : argTypes) {
                    returnClasses[i++] = (Class<?>) argType;
                }
                return returnClasses;
            }
        }
        throw new RuntimeException(method.toGenericString() + "不含泛型" + argClass);
    }

    public static Class<?> getMethodGenericityClass(Method method, Class<?> argClass, int index) {
        Class<?> genericityClasses[] = getMethodGenericityClass(method, argClass);
        if (genericityClasses.length < index) {
            throw new RuntimeException("泛型参数个数少于" + index);
        }
        return genericityClasses[index];
    }
}
